"""
RPA服务类 - 管理多个平台的RPA任务
负责协调Facebook和LinkedIn等平台的自动化任务执行
"""
import asyncio
import uuid
from typing import Dict, Any, Optional, List
from datetime import datetime
from core.chrome_manager import get_chrome_manager
from core.platforms.facebook.facebook import FaceBookClient
from core.platforms.linkedin.linkedin import LinkedInClient
from core.utils.logger_manager import LoggerManager
from database.connection import db_manager
from database.repositories import TaskRepository
from core.cookies_manager import CookiesManager

class RPAService:
    """RPA服务类 - 管理多个平台的RPA任务"""
    
    def __init__(self):
        self.logger = LoggerManager.get_logger("rpa_service")
        self.chrome_manager = get_chrome_manager()
        self.facebook_client: Optional[FaceBookClient] = None
        self.linkedin_client: Optional[LinkedInClient] = None
        self.running_tasks: Dict[str, Dict[str, Any]] = {}
        self.cookies_manager = CookiesManager()

    async def create_facebook_client(self, debug_port: int,cookie:List[Dict[str, Any]],task_id:str) -> FaceBookClient:
        """创建Facebook客户端"""
        try:
            client = FaceBookClient(debug_port=debug_port,cookie=cookie,task_id=task_id)
            self.logger.info(f"Facebook客户端创建成功，端口: {debug_port}")
            return client
        except Exception as e:
            self.logger.error(f"创建Facebook客户端失败: {str(e)}")
            raise
    
    async def create_linkedin_client(self, debug_port: int,cookie:List[Dict[str, Any]],task_id:str) -> LinkedInClient:
        """创建LinkedIn客户端"""
        try:
            client = LinkedInClient(debug_port=debug_port,cookie=cookie,task_id=task_id)
            self.logger.info(f"LinkedIn客户端创建成功，端口: {debug_port}")
            return client
        except Exception as e:
            self.logger.error(f"创建LinkedIn客户端失败: {str(e)}")
            raise
    
    async def _init_platform_client(self, platform: str, create_client_func, proxy_config: Dict[str, str] = None,task_id:str=None):
        """通用平台客户端初始化方法"""
        cookies = self.cookies_manager.list_cookies_files(platform)
        cookie = cookies[0] if cookies else []
        browser_id = self.chrome_manager.create_browser(proxy_config=proxy_config)
        if not browser_id:
            raise Exception(f"{platform.capitalize()}浏览器创建失败")
        browser_detail = self.chrome_manager.get_browser_detail(browser_id)
        if not browser_detail:
            raise Exception(f"{platform.capitalize()}浏览器详情获取失败")
        client = await create_client_func(browser_detail['debug_port'], cookie,task_id)
        return browser_id, browser_detail['debug_port'], client


    async def start_platform_clients(self, proxy_config: Dict[str, str] = None) -> Dict[str, str]:
        """启动多个平台的客户端"""
        try:
           
            fb_id, fb_port, fb_client = await self._init_platform_client(
                "facebook", self.create_facebook_client, proxy_config
            )
            
            li_id, li_port, li_client = await self._init_platform_client(
                "linkedin", self.create_linkedin_client, proxy_config
            )
            self.facebook_client = fb_client
            self.linkedin_client = li_client
            result = {
                "facebook_browser_id": fb_id,
                "linkedin_browser_id": li_id,
                "facebook_debug_port": fb_port,
                "linkedin_debug_port": li_port
            }
            self.logger.info(f"平台客户端启动成功: {result}")
            return result
        except Exception as e:
            self.logger.error(f"启动平台客户端失败: {str(e)}")
            await self.cleanup_browsers()
            raise
        
    async def run_facebook_task(self, task_id: str, proxy_config: Dict[str, str] = None,**kwargs) -> Dict[str, Any]:
        """运行Facebook任务"""
        try:
            self.logger.info(f"🟢 初始化浏览器中...", extra={"show_in_ui": 1, "task_id": task_id})
            _, _, self.facebook_client = await self._init_platform_client(
                "facebook", self.create_facebook_client, proxy_config,task_id=task_id
            )
            
            self.logger.info(f"🚀 开始facebook任务", extra={"show_in_ui": 1, "task_id": task_id})
            result = await self.facebook_client.run_task(task_id, **kwargs)
            self.logger.info(f"✅ facebook 完成", extra={"show_in_ui": 1, "task_id": task_id})
            return result
            
        except Exception as e:
            self.logger.error(f"Facebook任务失败: {task_id}, 错误: {str(e)}")
            return {
                "task_id": task_id,
                "status": "failed",
                "step": {'error':str(e)},
            }
    
    async def run_linkedin_task(self, task_id: str, proxy_config: Dict[str, str] = None, **kwargs) -> Dict[str, Any]:
        """运行LinkedIn任务"""
        try:
            self.logger.info(f"🟢 初始化浏览器中...", extra={"show_in_ui": 1, "task_id": task_id})
            _, _, self.linkedin_client = await self._init_platform_client(
                "linkedin", self.create_linkedin_client, proxy_config,task_id=task_id
            )
            
            self.logger.info(f"🚀 开始linkedin任务", extra={"show_in_ui": 1, "task_id": task_id})
            result = await self.linkedin_client.run_task(task_id, **kwargs)
            self.logger.info(f"✅ linkedin 完成", extra={"show_in_ui": 1, "task_id": task_id})
            return result
            
        except Exception as e:
            self.logger.error(f"LinkedIn任务失败: {task_id}, 错误: {str(e)}")
            return {
                "task_id": task_id,
                "status": "failed",
                "step": {'error':str(e)},
            }
    
    async def run_concurrent_tasks(self, task_id: str, facebook_params: Dict[str, Any] = None, 
                                 linkedin_params: Dict[str, Any] = None) -> Dict[str, Any]:
        """并发运行Facebook和LinkedIn任务"""
        try:
            self.logger.info(f"开始并发执行任务: {task_id}")
            # 创建子任务ID
            facebook_subtask_id = f"{task_id}_facebook"
            linkedin_subtask_id = f"{task_id}_linkedin"
              
          
            # 准备任务参数
            tasks = []
            if facebook_params:
                # 提取proxy_config，避免参数重复
                fb_proxy = facebook_params.get('proxy_config')
                fb_params = {k: v for k, v in facebook_params.items() if k != 'proxy_config'}
                tasks.append(self.run_facebook_task(facebook_subtask_id, fb_proxy, **fb_params))
            
            if linkedin_params:
                # 提取proxy_config，避免参数重复
                li_proxy = linkedin_params.get('proxy_config')
                li_params = {k: v for k, v in linkedin_params.items() if k != 'proxy_config'}
                tasks.append(self.run_linkedin_task(linkedin_subtask_id, li_proxy, **li_params))
            
            if not tasks:
                raise Exception("没有有效的任务参数")
            
            # 并发执行任务
            results = await asyncio.gather(*tasks, return_exceptions=True)

            self.logger.info(f"并发任务完成: {task_id}")
            return results
            
        except Exception as e:
            self.logger.error(f"并发任务失败: {task_id}, 错误: {str(e)}")
            return {
                "task_id": task_id,
                "status": "failed",
                "error": str(e),
                "completed_at": datetime.utcnow().isoformat()
            }
    
    async def cleanup_browsers(self):
        """清理浏览器资源"""
        try:
            if self.facebook_client:
                await self.facebook_client.close()
                self.facebook_client = None
            
            if self.linkedin_client:
                await self.linkedin_client.close()
                self.linkedin_client = None
            
            # 清理所有浏览器
            browsers = self.chrome_manager.get_browser_list()
            for browser in browsers:
                if browser.get('status') == 'running':
                    self.chrome_manager.delete_browser(browser['id'])
            
            self.logger.info("浏览器资源清理完成")
            
        except Exception as e:
            self.logger.error(f"清理浏览器资源失败: {str(e)}")
    
    async def get_task_status(self, task_id: str) -> Optional[Dict[str, Any]]:
        """获取任务状态"""
        return self.running_tasks.get(task_id)
    
    async def cancel_task(self, task_id: str) -> bool:
        """取消任务"""
        try:
            if task_id in self.running_tasks:
                task_info = self.running_tasks[task_id]
                task_info['status'] = 'cancelled'
                task_info['cancelled_at'] = datetime.utcnow().isoformat()
                
                # 清理浏览器资源
                await self.cleanup_browsers()
                
                self.logger.info(f"任务已取消: {task_id}")
                return True
            
            return False
            
        except Exception as e:
            self.logger.error(f"取消任务失败: {task_id}, 错误: {str(e)}")
            return False


# 全局RPA服务实例
rpa_service = RPAService()


def get_rpa_service() -> RPAService:
    """获取RPA服务实例"""
    return rpa_service